package com.ncmmall.mall.controller.business.marketing;

import cn.hutool.core.util.StrUtil;
import com.ncmmall.application.business.marketing.SeckillApplication;
import com.feijin.commons.exceptions.IllegalRequestException;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.business.goods.sku.GoodsSku;
import com.ncmmall.domain.business.goods.sku.QGoodsSku;
import com.ncmmall.domain.business.marketing.seckill.QSeckillActivity;
import com.ncmmall.domain.business.marketing.seckill.QSeckillSession;
import com.ncmmall.domain.business.marketing.seckill.SeckillActivity;
import com.ncmmall.domain.business.marketing.seckill.SeckillGoods;
import com.ncmmall.domain.business.marketing.seckill.SeckillSession;
import com.ncmmall.mall.params.PageParams;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 秒杀活动管理
 *
 * @author linxs
 * @date 2020-02-03 14:35
 */
@Slf4j
@Controller
@RequestMapping(value = "/mall/seckill")
public class SeckillActivityController {

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private SeckillApplication seckillApplication;

    /**
     * 商品列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    private String list(Model model, PageParams pageParams, SeckillActivity seckill) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = new HashMap<>();
        String hql = builderSQL("select u from SeckillActivity u where 1 = 1 ", params, seckill);
        QueryPage<SeckillActivity> page = queryChannelService.findPage(hql, pageRequest.setParams(params), SeckillActivity.class);
        model.addAttribute("page", page).addAttribute("params", seckill);
        return "mall/marketing/seckill/list";
    }


    /**
     * 详情
     */
    @RequestMapping(value = "/{id}/detail", method = RequestMethod.GET)
    private String detail(Model model, @PathVariable("id") long id) {

        SeckillActivity seckillActivity = queryChannelService.findOne(QSeckillActivity.seckillActivity.id.eq(id), SeckillActivity.class);

        List<SeckillGoods> goodses = queryChannelService.findAll("select s from SeckillGoods s where s.seckillActivity.id = :id ", ImmutableMap.of("id", seckillActivity.getId()), SeckillGoods.class);

        for (SeckillGoods goodse : goodses) {
            List<GoodsSku> skus = queryChannelService.findAll(QGoodsSku.goodsSku.goods.eq(goodse.getGoods()), GoodsSku.class);
            goodse.getGoods().setSkus(skus);
        }

        List<SeckillSession> seckillSessions = queryChannelService.findAll("select s from SeckillSession s where s.status = 2 and s.isValidity = 1 and now() < s.applyDeadline ", SeckillSession.class);
        model.addAttribute("seckill", seckillActivity).addAttribute("seckillSessions", seckillSessions).addAttribute("seckillGoodses", goodses).addAttribute("_method", "PUT");

        return "mall/marketing/seckill/detail";

    }


    /**
     * 审核
     */
    @RequestMapping(value = "/{id}/process", method = RequestMethod.GET)
    public String process(Model model, @PathVariable("id") long id) {

        SeckillActivity seckillActivity = queryChannelService.findOne(QSeckillActivity.seckillActivity.id.eq(id), SeckillActivity.class);

        List<SeckillGoods> goodses = queryChannelService.findAll("select s from SeckillGoods s where s.seckillActivity.id = :id ", ImmutableMap.of("id", seckillActivity.getId()), SeckillGoods.class);

        for (SeckillGoods goodse : goodses) {
            List<GoodsSku> skus = queryChannelService.findAll(QGoodsSku.goodsSku.goods.eq(goodse.getGoods()), GoodsSku.class);
            goodse.getGoods().setSkus(skus);
        }

        List<SeckillSession> seckillSessions = queryChannelService.findAll("select s from SeckillSession s where s.status = 2 and s.isValidity = 1 and now() < s.applyDeadline ", SeckillSession.class);
        model.addAttribute("seckill", seckillActivity).addAttribute("seckillSessions", seckillSessions).addAttribute("seckillGoodses", goodses).addAttribute("_method", "PUT");

        return "mall/marketing/seckill/check";

    }

    /**
     * 审核
     */
    @RequestMapping(value = "/{id}/process", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> process(@RequestHeader("X-Requested-With") String requestWith, SeckillActivity seckillActivity) {

        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            seckillApplication.processSeckillActivity(seckillActivity);
            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[编辑秒杀活动异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 查询秒杀场次信息
     */
    @RequestMapping(value = "/querySession", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> querySession(@RequestParam("id") long id) {
        SeckillSession seckillSession = queryChannelService.findOne(QSeckillSession.seckillSession.id.eq(id), SeckillSession.class);
        return ImmutableMap.of("status", true, "seckillSession", seckillSession);
    }


    /**
     * 条件筛选
     */
    private String builderSQL(String sql, Map<String, Object> params, SeckillActivity seckillActivity) {
        if (seckillActivity.getSeckillSession() != null && StrUtil.isNotBlank(seckillActivity.getSeckillSession().getName())) {
            sql += " and u.seckillSession.name like :name";
            params.put("name", "%" + seckillActivity.getSeckillSession().getName() + "%");
        }
        if (seckillActivity.getStatus() == 0) {
            sql += " and u.status in (2, 3, 4) ";
        } else {
            sql += " and u.status = :status ";
            params.put("status", seckillActivity.getStatus());
        }
        return sql + " order by u.createTime desc";
    }

}
